package ruc.TDEngine.accuracy;

import cn.hutool.core.codec.Base64;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import ruc.Consts.constant;
import ruc.TDEngine.TDEngine_Common;
import ruc.utils.IOUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;

class Info {
    float cpu_usage, memory_usage, disk_usage;
    public Info(float cpu_usage, float memory_usage, float disk_usage){
        this.cpu_usage = cpu_usage;
        this.memory_usage = memory_usage;
        this.disk_usage = disk_usage;
    }
}

public class TDengine_Accuracy {
    private String IP, port, dbName, tbName,userName,password;

    public TDengine_Accuracy(String IP, String port, String dbName, String tbName, String userName, String password) {
        this.IP = IP;
        this.port = port;
        this.dbName = dbName;
        this.tbName = tbName;
        this.userName = userName;
        this.password = password;
    }

    private HashMap convert(String[] list) throws IOException {
        HashMap<String, Info> map = new HashMap();
        for(int k = 0; k < list.length; k++) {
            String[] v = list[k].split(constant.Delimiter);
            Info info = new Info(Float.parseFloat(v[4]), Float.parseFloat(v[5]), Float.parseFloat(v[6]));
            map.put(Long.parseLong(v[0]) + v[1] + v[2] + v[3], info);
        }
        return map;
    }

    public Request getRequest(String query) {
        String Authorization = Base64.encode(String.format("%s:%s", userName, password).getBytes(StandardCharsets.UTF_8));
        String URL = String.format("http://%s:%s/rest/sql", IP, port);

        return new Request.Builder()
                .url(URL)
                .method("POST", RequestBody.create(MediaType.parse("text/plain"),query))
                .addHeader("Authorization", "Basic "+Authorization)
                .addHeader("Content-Type", "text/plain")
                .build();
    }

    private float loopBasicType(String str, HashMap<String, Info> map) {
        float res = 0;
        JSONArray jsonArray = JSONUtil.parseArray(str);
        for (int i = 0; i < jsonArray.size(); i++) {
            String ts = jsonArray.getJSONObject(i).getStr("timestamp");
            String ui = jsonArray.getJSONObject(i).getStr("userInfo");
            String hs = jsonArray.getJSONObject(i).getStr("hostname");
            String server = jsonArray.getJSONObject(i).getStr("server");
            String key = ts + ui + hs + server;
            String cup_usage = jsonArray.getJSONObject(i).getStr("cpu_usage");
            String memory_usage = jsonArray.getJSONObject(i).getStr("memory_usage");
            String disk_usage = jsonArray.getJSONObject(i).getStr("disk_usage");
            Info info = map.get(key);

            res += Math.pow(info.cpu_usage - Float.parseFloat(cup_usage), 2);
            res += Math.pow(info.disk_usage - Float.parseFloat(disk_usage), 2);
            res += Math.pow(info.memory_usage - Float.parseFloat(memory_usage), 2);
        }

        return res / jsonArray.size();
    }

    private float calAccuracy() throws IOException {
        Response response = TDEngine_Common.send(getRequest(String.format("select * from %s", tbName)));
        assert response != null;
        response.close();
        response.body();
        HashMap map = convert(IOUtils.GetData());
        return loopBasicType(response.body().string(), map);
    }
}
